﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Security;
using System.Management;
using System.Net.Sockets;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication
{
    public partial class NetForm : Form
    {
        public NetForm()
        {
            InitializeComponent();
        }

        private void btnARP_Click(object sender, EventArgs e)
        {
            GetHostInfo();
        }

        private void GetHostInfo()
        {
            try
            {
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (var item in moc)
                {
                    txtContent.Text += string.Format("{0} : {1}\r\n", item["Caption"], item["MacAddress"]);
                }
            }
            catch (Exception ex)
            {
                txtContent.Text = ex.Message;
            }
        }

        private void btnListen_Click(object sender, EventArgs e)
        {
            txtContent.Text = string.Empty;
            Listener();
        }

        private string Listener()
        {
            string msg = string.Empty;
            try
            {
                RawSocket rs = new RawSocket();
                rs.CreateAndBindSocket("157.60.108.184");
                rs.Run();
                rs.Shutdown();
            }
            catch (Exception ex)
            {
                msg = ex.Message;
            }
            return msg;
        }
    }
    /// <summary>
    /// Socket struct
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct IPHeader
    {
        [FieldOffset(0)]
        public byte ip_verlen; //I4位首部长度+4位IP版本号 
        [FieldOffset(1)]
        public byte ip_tos; //8位服务类型TOS 
        [FieldOffset(2)]
        public ushort ip_totallength; //16位数据包总长度（字节） 
        [FieldOffset(4)]
        public ushort ip_id; //16位标识 
        [FieldOffset(6)]
        public ushort ip_offset; //3位标志位 
        [FieldOffset(8)]
        public byte ip_ttl; //8位生存时间 TTL 
        [FieldOffset(9)]
        public byte ip_protocol; //8位协议(TCP, UDP, ICMP, Etc.) 
        [FieldOffset(10)]
        public ushort ip_checksum; //16位IP首部校验和 
        [FieldOffset(12)]
        public uint ip_srcaddr; //32位源IP地址 
        [FieldOffset(16)]
        public uint ip_destaddr; //32位目的IP地址 
    }
    public class RawSocket
    {
        private bool error_occurred; //套接字在接收包时是否产生错误 
        public bool KeepRunning; //是否继续进行 
        private static int len_receive_buf; //得到的数据流的长度 
        public byte[] receive_buf_bytes; //收到的字节 
        private Socket socket = null; //声明套接字

        const int SIO_RCVALL = unchecked((int)0x98000001);//监听所有的数据包 

        public RawSocket() //构造函数 
        {
            error_occurred = false;
            len_receive_buf = 4096;
            receive_buf_bytes = new byte[len_receive_buf];
        }
        public void CreateAndBindSocket(string IP) //建立并绑定套接字 
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
            socket.Blocking = false; //置socket非阻塞状态 
            socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0)); //绑定套接字 

            if (SetSocketOption() == false) error_occurred = true;
        }
        private bool SetSocketOption() //设置raw socket 
        {
            bool ret_value = true;
            try
            {
                socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
                byte[] IN = new byte[4] { 1, 0, 0, 0 };
                byte[] OUT = new byte[4];
                //低级别操作模式,接受所有的数据包，这一步是关键，必须把socket设成raw和IP Level才可用　　SIO_RCVALL 
                int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
                ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];//把4个8位字节合成一个32位整数 
                if (ret_code != 0) ret_value = false;
            }
            catch (SocketException)
            {
                ret_value = false;
            }
            return ret_value;
        }
        public bool ErrorOccurred
        {
            get
            {
                return error_occurred;
            }
        }
        unsafe private void Receive(byte[] buf, int len)
        {
            byte temp_protocol = 0;
            uint temp_version = 0;
            uint temp_ip_srcaddr = 0;
            uint temp_ip_destaddr = 0;
            short temp_srcport = 0;
            short temp_dstport = 0;
            IPAddress temp_ip;

            PacketArrivedEventArgs e = new PacketArrivedEventArgs();//新网络数据包信息事件 

            fixed (byte* fixed_buf = buf)
            {
                IPHeader* head = (IPHeader*)fixed_buf;//把数据流整和为IPHeader结构 
                e.HeaderLength = (uint)(head->ip_verlen & 0x0F) << 2;

                temp_protocol = head->ip_protocol;
                switch (temp_protocol)//提取协议类型 
                {
                    case 1: e.Protocol = "ICMP"; break;
                    case 2: e.Protocol = "IGMP"; break;
                    case 6: e.Protocol = "TCP"; break;
                    case 17: e.Protocol = "UDP"; break;
                    default: e.Protocol = "UNKNOWN"; break;
                }

                temp_version = (uint)(head->ip_verlen & 0xF0) >> 4;//提取IP协议版本 
                e.IPVersion = temp_version.ToString();

                //以下语句提取出了PacketArrivedEventArgs对象中的其他参数 
                temp_ip_srcaddr = head->ip_srcaddr;
                temp_ip_destaddr = head->ip_destaddr;
                temp_ip = new IPAddress(temp_ip_srcaddr);
                e.OriginationAddress = temp_ip.ToString();
                temp_ip = new IPAddress(temp_ip_destaddr);
                e.DestinationAddress = temp_ip.ToString();
                temp_srcport = *(short*)&fixed_buf[e.HeaderLength];
                temp_dstport = *(short*)&fixed_buf[e.HeaderLength + 2];
                e.OriginationPort = IPAddress.NetworkToHostOrder(temp_srcport).ToString();
                e.DestinationPort = IPAddress.NetworkToHostOrder(temp_dstport).ToString();

                e.PacketLength = (uint)len;
                e.MessageLength = (uint)len - e.HeaderLength;

                e.ReceiveBuffer = buf;
                //把buf中的IP头赋给PacketArrivedEventArgs中的IPHeaderBuffer 
                Array.Copy(buf, 0, e.IPHeaderBuffer, 0, (int)e.HeaderLength);
                //把buf中的包中内容赋给PacketArrivedEventArgs中的MessageBuffer 
                Array.Copy(buf, (int)e.HeaderLength, e.MessageBuffer, 0, (int)e.MessageLength);
            }
            //引发PacketArrival事件 
            OnPacketArrival(e);
        }
        public void Run() //开始监听 
        {
            IAsyncResult ar = socket.BeginReceive(receive_buf_bytes, 0, len_receive_buf, SocketFlags.None, new AsyncCallback(CallReceive), this);
        }
        private void CallReceive(IAsyncResult ar)//异步回调 
        {
            int received_bytes;
            received_bytes = socket.EndReceive(ar);
            Receive(receive_buf_bytes, received_bytes);
            if (KeepRunning) Run();
        }
        public void Shutdown() //关闭raw socket 
        {
            if (socket != null)
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
        }
        public class PacketArrivedEventArgs : EventArgs
        {
            public PacketArrivedEventArgs()
            {
                this.protocol = "";
                this.destination_port = "";
                this.origination_port = "";
                this.destination_address = "";
                this.origination_address = "";
                this.ip_version = "";

                this.total_packet_length = 0;
                this.message_length = 0;
                this.header_length = 0;

                this.receive_buf_bytes = new byte[len_receive_buf];
                this.ip_header_bytes = new byte[len_receive_buf];
                this.message_bytes = new byte[len_receive_buf];
            }

            public string Protocol
            {
                get { return protocol; }
                set { protocol = value; }
            }
            public string DestinationPort
            {
                get { return destination_port; }
                set { destination_port = value; }
            }
            public string OriginationPort
            {
                get { return origination_port; }
                set { origination_port = value; }
            }
            public string DestinationAddress
            {
                get { return destination_address; }
                set { destination_address = value; }
            }
            public string OriginationAddress
            {
                get { return origination_address; }
                set { origination_address = value; }
            }
            public string IPVersion
            {
                get { return ip_version; }
                set { ip_version = value; }
            }
            public uint PacketLength
            {
                get { return total_packet_length; }
                set { total_packet_length = value; }
            }
            public uint MessageLength
            {
                get { return message_length; }
                set { message_length = value; }
            }
            public uint HeaderLength
            {
                get { return header_length; }
                set { header_length = value; }
            }
            public byte[] ReceiveBuffer
            {
                get { return receive_buf_bytes; }
                set { receive_buf_bytes = value; }
            }
            public byte[] IPHeaderBuffer
            {
                get { return ip_header_bytes; }
                set { ip_header_bytes = value; }
            }
            public byte[] MessageBuffer
            {
                get { return message_bytes; }
                set { message_bytes = value; }
            }
            private string protocol;
            private string destination_port;
            private string origination_port;
            private string destination_address;
            private string origination_address;
            private string ip_version;
            private uint total_packet_length;
            private uint message_length;
            private uint header_length;
            private byte[] receive_buf_bytes = null;
            private byte[] ip_header_bytes = null;
            private byte[] message_bytes = null;
        }

        public delegate void PacketArrivedEventHandler(Object sender, PacketArrivedEventArgs args);

        public event PacketArrivedEventHandler PacketArrival;

        protected virtual void OnPacketArrival(PacketArrivedEventArgs e)
        {
            if (PacketArrival != null)
            {
                PacketArrival(this, e);
            }
        }
    }
}
